﻿
/***更新****************************************************************   
*       最后更新 : ZhangJunhua   
*       更新日期 : 2010/04/15   
*       更新目的 : 增加  功能；修复bug   
*       更新版本 : 1.00   
*       更新日志 : 日志   
************************************************************************/     
  
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
using System.MathTools;
using System.MathTools.Statistics;


namespace NormalProbPlot
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            x1.Visibility = Visibility.Collapsed;
            x2.Visibility = Visibility.Collapsed;
            x3.Visibility = Visibility.Collapsed;
            x4.Visibility = Visibility.Collapsed;
            x5.Visibility = Visibility.Collapsed;
            txtInput.Text = @"66	67	68	69	69	70	70	71	
72	73	73	74	74	75	76	77	";

            cmbScale.Items.Add("0.5");
            cmbScale.Items.Add("1.0");
            cmbScale.Items.Add("1.5");
            cmbScale.Items.Add("2.0");
            cmbScale.Items.Add("3.0");
            cmbScale.Items.Add("5.0");
            cmbScale.Items.Add("10.0");
            cmbScale.DropDownClosed += new EventHandler(cmbScale_DropDownClosed);
        }

        void cmbScale_DropDownClosed(object sender, EventArgs e)
        {
            try
            {
                SaveAsImage.SaveToImage(cnsDraw,
                Convert.ToDouble(cmbScale.SelectedItem.ToString()));
            }
            catch (Exception)
            {
                MessageBox.Show("未选择缩放值！");
            }            
        }
 
        private void btn_Clear_Click(object sender, RoutedEventArgs e)
        {
            txtInput.Text = "";
        }

        private void btn_Submit_Click(object sender, RoutedEventArgs e)
        {
            txtInput.Text = txtInput.Text.Replace("\r\n", "\n");
            txtInput.Text = txtInput.Text.Replace("\t\n", "\n");
            txtInput.Text = txtInput.Text.Replace(" \n", "\n");
            txtInput.Text = txtInput.Text.TrimStart(" \r\n\t".ToArray());
            txtInput.Text = txtInput.Text.TrimEnd(" \r\n\t".ToArray());
            StringTokenizer divideTokenizer = new StringTokenizer(txtInput.Text, "\n\t, :;");
            int pointNumber = divideTokenizer.countTokens();
            int i = 0;
            double[] pt = new double[pointNumber];
            try
            {
                while (divideTokenizer.hasMoreTokens())
                {
                    pt[i++] = Convert.ToDouble(divideTokenizer.nextToken());
                }
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
                return;
            }
            DrawNP(pt);
        }

        void MovePoint(Path pt, double ptX, double ptY)
        {
            pt.SetValue(Canvas.LeftProperty, ptX + 0.4);
            pt.SetValue(Canvas.TopProperty, ptY + 1.8);
        }

        void DrawNP(double[] pt)
        {
            int l = 0;
            double[] normalPt = new double[pt.Length];
            pt = System.MathTools.MathUtil.sort(pt);
            double xMin = pt[0];
            double xMax = pt[pt.Length - 1];
            double xRange = xMax - xMin;
            double xUnit = 240.0 / xRange;
            double yUnit = 30.0;

            InvNormCdf invNormCdf = new InvNormCdf(0.0, 1.0);

            for (l = lst_point.Count - 1; l > pt.Length - 1; l--)
            {
                cnsDraw.Children.Remove(lst_point.ElementAt(l));
            }

            if (lst_point.Count < pt.Length)
            {

                for (; pt.Length > lst_point.Count; )
                {
                    lst_point.Add(DrawPoint(0, 0));
                }
            }

            for (l = 0; l < pt.Length; l++)
            {
                if (!cnsDraw.Children.Contains(lst_point.ElementAt(l)))
                    cnsDraw.Children.Add(lst_point.ElementAt(l));
            }

            if (pt.Length == 1)
            {
                lnNQ.Visibility =
                x1.Visibility =
                x2.Visibility =
                x4.Visibility =
                x5.Visibility = Visibility.Collapsed;
                x3.Visibility = Visibility.Visible;

                x3.Text = pt[0].ToString();
                MovePoint(lst_point.ElementAt(0), 170, 120);
            }
            else
            {
                x1.Visibility =
                x2.Visibility =
                x3.Visibility =
                x4.Visibility =
                x5.Visibility = Visibility.Visible;

                for (l = 0; l < pt.Length; l++)
                {
                    normalPt[l] = invNormCdf.approximation((((double)l + 1.0D) - 0.5D) / (double)pt.Length);
                    MovePoint(lst_point.ElementAt(l), 50 + (pt[l] - xMin) * xUnit,
                        30 + (3 - normalPt[l]) * yUnit);
                }
                double beta1 = (MathUtil.arraySum(normalPt, pt) -
                    (MathUtil.arraySum(normalPt) * MathUtil.arraySum(pt))
                    / (double)pt.Length) / (MathUtil.arraySquareSum(pt)
                    - Math.Pow(MathUtil.arraySum(pt), 2D) / (double)pt.Length);
                double beta0 = MathUtil.arraySum(normalPt) /
                    (double)normalPt.Length - (beta1 * MathUtil.arraySum(pt)) /
                    (double)pt.Length;
                x1.Text = xMin.ToString("f2");
                x2.Text = (xMin + xRange / 4D).ToString("f2");
                x3.Text = (xMin + (xRange * 2D) / 4D).ToString("f2");
                x4.Text = (xMin + (xRange * 3D) / 4D).ToString("f2");
                x5.Text = xMax.ToString("f2");

                lnNQ.X1 = 50;
                lnNQ.X2 = 290;
                lnNQ.Y1 = (int)(30 + (3 - beta0 - beta1 * xMin) * yUnit);
                lnNQ.Y2 = (int)(30 + (3 - beta0 - beta1 * xMax) * yUnit);
                lnNQ.Visibility = Visibility.Visible;
            }
        }

        Path DrawPoint(double ptX, double ptY)
        {
            Path pth = new Path();
            pth.Stroke = new SolidColorBrush(Color.FromArgb(0xff, 0xff, 0, 0));
            PathFigure pthf = new PathFigure();
            PathGeometry pathGeometry = new PathGeometry();
            LineSegment ls = new LineSegment();
            pthf.StartPoint = new Point(ptX - 1.8, ptY - 1.8);
            ls.Point = new Point(ptX + 1.8, ptY + 1.8);
            pthf.Segments.Add(ls);
            pathGeometry.Figures.Add(pthf);
            pthf = new PathFigure();
            ls = new LineSegment();
            pthf.StartPoint = new Point(ptX - 1.8, ptY + 1.8);
            ls.Point = new Point(ptX + 1.8, ptY - 1.8);
            pthf.Segments.Add(ls);
            pathGeometry.Figures.Add(pthf);
            pth.Data = pathGeometry;
            return pth;
        }

        private void btn_SavePic_Click(object sender, RoutedEventArgs e)
        {
            SaveAsImage.SaveToImage(cnsDraw, 10);
        }

        List<Path> lst_point = new List<Path>();
    }
}
